home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / rukc10.zip / X02M.C < prev    next >
C/C++ Source or Header  |  1993-03-06  |  6KB  |  208 lines

  1.  
  2. #include <dos.h>
  3. #include <conio.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7.  
  8. #include "ruckmidi.h"
  9.  
  10. /*
  11. X02M.c 28-Feb-93 chh
  12. OutMsgMidi example
  13. */
  14.  
  15. /*
  16. The following structures are in ruckdac.h
  17. */
  18.  
  19. extern struct MidiDataArea __pascal MIDIDATA;
  20.  
  21. struct SysInfoMidiPack SIMP;
  22. struct InitMidiPack IMP;
  23. struct XitMidiPack XMP;
  24. struct LoadMidiPack LMP;
  25. struct SetMidiPack SMP;
  26. struct SetFMProPack SFMPP;
  27. struct PlaybackMidiPack PBMP;
  28. struct OutMsgMidiPack OMMP;
  29. struct DeallocMidiPack DMP;
  30.  
  31.  
  32. int rez, rez2;      /* result status codes */
  33. char nums[9] = {7}; /* number buffer for _cgets()*/
  34. char filename[81];  /* pathname to load */
  35.  
  36.  
  37. int main()
  38. {
  39.  
  40.     int pc=0, sSize=0;
  41.     unsigned i=0;
  42.     unsigned pitchbend=0x2000;  /* mid-value of 0-8192 range */
  43.  
  44.     printf("\nX02M.C - RUCKUS-MIDI OutMsgMidi example. [930228]\n");
  45.  
  46.     /*
  47.     Initialize RUCKMIDI and device and register ExitMidi with _atexit
  48.     */
  49.  
  50.     IMP.Func = InitMidi;
  51.     IMP.DeviceID = 1;           /* OPL-2 percussive mode */
  52.     IMP.IOport = 0x388;
  53.     IMP.ChMask = 0x23F;
  54.     IMP.PercCh = 9;
  55.     IMP.Flags = 0;
  56.     rez = RUCKMIDI(&IMP);                 /* Initialize */
  57.     if (rez == 0) {
  58.  
  59.         XMP.Func = AtExitMidi;
  60.         rez2 = RUCKMIDI(&XMP);
  61.         if (rez2 != 0) {
  62.             printf("AtExitMidi failed, press Enter to continue");
  63.             getchar();
  64.         }
  65.  
  66.         /*
  67.         Increase SB Pro main and FM vol volumes to max
  68.         */
  69.  
  70.         SFMPP.Func = SetAllFMSBP;
  71.         SFMPP.IOport = 0x220;       /* if there it'll respond */
  72.         SFMPP.MasterVol = 0x0F0F;   /* if not, no problem */
  73.         SFMPP.Steer = 0;
  74.         SFMPP.FMvol = 0x0F0F;
  75.         rez2 = RUCKMIDI(&SFMPP);
  76.  
  77.  
  78.         /*
  79.         Set patch map to, oh, let's use GM
  80.         */
  81.  
  82.         SMP.Func = SetPatchMidi;
  83.         SMP.PatchMapID = 0;     /* actually, this is the GM is the default */
  84.         SMP.PatchMapPtr = NULL;
  85.         rez2 = RUCKMIDI(&SMP);
  86.  
  87.         do {
  88.             printf("\nProgram# to sound (0-127, -1 to end): ");
  89.             pc = atoi(_cgets(nums));
  90.             if ((pc < 0) || (pc > 127))
  91.                 break;
  92.  
  93.             OMMP.Func = OutMsgMidi;
  94.             OMMP.Mstatus = 0xC0;    /* channel 0 program change */
  95.             OMMP.Mdata = pc;
  96.             rez2 = RUCKMIDI(&OMMP);
  97.  
  98.             printf("\n------------------------------------");
  99.             printf("\nChannel 0 is using program number: %i\n",pc);
  100.  
  101.             /*
  102.             In NoteOn Mdata is key number (0-127 MIDI, but OPL-2 key
  103.             numbers are valid from 12 to 107, see docs for more)
  104.             in the low byte. Key velocity (0-127) is in the high byte.
  105.             --velocity is essentially the volume desired.
  106.             */
  107.  
  108.             OMMP.Func = OutMsgMidi; /* really don't need to set it again */
  109.             OMMP.Mstatus = 0x90;    /* NoteOn, channel 0 */
  110.             OMMP.Mdata = 0x7F3C;    /* note=60 = 262Hz, max volume=7F */
  111.             rez2 = RUCKMIDI(&OMMP);
  112.  
  113.             printf("Playing a note with the NoteOn command\n");
  114.             printf("Press Enter to send NoteOff command...\n");
  115.             printf(" (NoteOn) ");
  116.             printf("Note: %u, Channel: %u, Volume: %u",
  117.                  (OMMP.Mdata & 0x7F),(OMMP.Mstatus & 0x0F),(OMMP.Mdata >>8));
  118.  
  119.             gets(filename);
  120.             printf(" (NoteOff)\n");
  121.  
  122.             /*
  123.             Note that sending a NoteOn (above) with velocity=0 has the same
  124.             effect as performing an explicit NoteOff--often in MIDI data
  125.             streams NoteOn with a velocity=0 is used rather than the specfic
  126.             NoteOff message--here the NoteOff message is used (with the
  127.             NoteOn method commented-out.
  128.             */
  129.  
  130.             OMMP.Func = OutMsgMidi;
  131.             OMMP.Mstatus = 0x80;    /* NoteOff, channel 0 */
  132.             OMMP.Mdata = 0;         /* any data will do */
  133.             rez2 = RUCKMIDI(&OMMP);
  134.  
  135.             /*
  136.             OMMP.Func = OutMsgMidi;
  137.             OMMP.Mstatus = 0x90;
  138.             OMMP.Mdata = 0x3C;
  139.             rez2 = RUCKMIDI(&OMMP);
  140.             */
  141.  
  142.             printf("\nPress Enter...");
  143.             gets(filename);
  144.  
  145.             /*
  146.             Do something a little more exciting than that.
  147.             See OutMsgMidi for more on MIDI channel messages in general.
  148.             */
  149.  
  150.             printf("Playing the same note but applying +/- pitchbend\n");
  151.  
  152.             OMMP.Func = OutMsgMidi;
  153.             OMMP.Mstatus = 0x90;    /* NoteOn, channel 0 */
  154.             OMMP.Mdata = 0x7F3C;    /* same note as above */
  155.             rez2 = RUCKMIDI(&OMMP);
  156.  
  157.             printf(" (NoteOn) ");
  158.             printf("Note: %u, Channel: %u, Volume: %u\n",
  159.                  (OMMP.Mdata & 0x7F),(OMMP.Mstatus & 0x0F),(OMMP.Mdata >>8));
  160.  
  161.             /*
  162.             Using just pitchbend this alters the frequency of the note being
  163.             played.
  164.             It's best to use a program that remains at the sustain level
  165.             until a NoteOff is sent--programs that have EG=1 will do so
  166.             (a high SL is also desired)(see OutMsgMidi for more).
  167.             */
  168.  
  169.             OMMP.Func = OutMsgMidi;
  170.             OMMP.Mstatus = 0xE0;    /* Pitchbend, channel 0 */
  171.  
  172.             sSize = 32;             /* CPU-speed dependent effect */
  173.  
  174.             for (i=0;i<10;i++) {
  175.                 for (pitchbend=0x2000;pitchbend > 0;pitchbend-=sSize) {
  176.                     OMMP.Mdata = pitchbend;
  177.                     rez2 = RUCKMIDI(&OMMP);
  178.                 }
  179.                 /* might want to put a check_key exit in here */
  180.                 for (pitchbend=0;pitchbend < 0x3FFF;pitchbend+=sSize) {
  181.                     OMMP.Mdata = pitchbend;
  182.                     rez2 = RUCKMIDI(&OMMP);
  183.                 }
  184.                 /* here too */
  185.                 for (pitchbend=0x3FFF;pitchbend > 0x2000;pitchbend-=sSize) {
  186.                     OMMP.Mdata = pitchbend;
  187.                     rez2 = RUCKMIDI(&OMMP);
  188.                 }
  189.             }
  190.  
  191.             OMMP.Func = OutMsgMidi;
  192.             OMMP.Mstatus = 0x80;        /* NoteOff, channel 0 */
  193.             OMMP.Mdata = 0;             /* any data */
  194.             rez2 = RUCKMIDI(&OMMP);
  195.             puts(" (NoteOff)");
  196.  
  197.         }
  198.         while (1);
  199.     }
  200.     else
  201.         printf("\nInitialization failed, %i\n",rez);
  202.  
  203. XMP.Func = ExitMidi;
  204. rez = RUCKMIDI(&XMP);
  205. return(rez);
  206.  
  207. }
  208.